<script setup lang="ts">

import Seats from '@/components/seats/Seats.vue'
import ReadyState from '@/components/state/ReadyState.vue'
import HuState from '@/components/state/HuState.vue'
import VersatileTiles from '@/components/tiles/versatile/VersatileTiles.vue'
import Operations from '@/components/operation/Operations.vue'

import OwnedTiles from '@/components/tiles/self/OwnedTiles.vue'
import OwnedTilesGroups from '@/components/tiles/self/OwnedTilesGroups.vue'
import OwnedHuaGroups from '@/components/tiles/hua/OwnedHuaGroups.vue'
import PlayedTiles from '@/components/tiles/self/PlayedTiles.vue'

import PreviousOwnedTiles from '@/components/tiles/previous/PreviousOwnedTiles.vue'
import PreviousOwnedTilesGroups from '@/components/tiles/previous/PreviousOwnedTilesGroups.vue'
import PreviousPlayedTiles from '@/components/tiles/previous/PreviousPlayedTiles.vue'

import NextOwnedTiles from '@/components/tiles/next/NextOwnedTiles.vue'
import NextOwnedTilesGroups from '@/components/tiles/next/NextOwnedTilesGroups.vue'
import NextPlayedTiles from '@/components/tiles/next/NextPlayedTiles.vue'

import OppositeOwnedTiles from '@/components/tiles/opposite/OppositeOwnedTiles.vue'
import OppositeOwnedTilesGroups from '@/components/tiles/opposite/OppositeOwnedTilesGroups.vue'
import OppositePlayedTiles from '@/components/tiles/opposite/OppositePlayedTiles.vue'

import {onMounted , ref, reactive, onUpdated} from 'vue'
import {useRouter} from 'vue-router'
import { UserFilled,Check,Close } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

import wsserver from '@/websocket/wsserver'
import operation from '@/constants/operation'
import msgtype from '@/constants/msgtype'
import tilesgroup from '@/constants/tilesgroup'

const router = useRouter();
let query = router.currentRoute.value.query;
const roomId:string = (query.roomId as string);
// 所有黑花
let HEI_HUA_TILES = ['MEI','LAN','ZHU','JU'];
// 所有红花
let HONG_HUA_TILES = ['CHUN', 'XIA','QIU','DONG'];

// 是否胡了
let isHu = ref(false);

// 判断该牌是否花牌
function isHua(tile:string) {
  return tile == 'BAI_BAN' || HEI_HUA_TILES.indexOf(tile) >= 0 || HONG_HUA_TILES.indexOf(tile) >= 0;
}

let desktop = ref(null);

// 是否正在进行中
let inProgress = ref(false);

// 百搭牌
let versatileTiles = ref(new Array<string>());

// 是否花牌
function isVersatile(tile:string) {
  return versatileTiles.value.indexOf(tile) >=0;
}

// 最近出的一张牌
let lastTile = ref('');

// 可以吃上家出的牌的牌组
let chiItGroups = ref(new Array<Array<string>>());

// 可以花暗杠的牌组
let huaAnGangGroups = ref(new Array<Array<string>>());

// 可以暗杠的牌组
let anGangTiles = ref(new Array<string>());

let mingGangTilesAfterGrabbing = ref(new Array<string>());

// 可以做的操作
let canOperation = reactive({
  // playCard: false,
  buHuaWhenStart: false,// 起手补花
  buHua: false, // 普通补花
  chi: false, // 吃
  peng: false, // 碰
  gangIt: false, // 杠某一张打出的牌
  mingGangAfterGrabbing: false, //摸牌之后明杠
  huaAnGang: false, // 花暗杠
  anGang: false, // 暗杠
  dianPao: false, // 点炮胡
  ziMo: false, // 自摸胡
})

// 初始化操作
function initCanOperation() {
  // canOperation.playCard = false;
  canOperation.buHuaWhenStart =  false;// 起手补花
  canOperation.buHua = false; // 普通补花
  canOperation.chi = false; // 吃
  canOperation.peng = false; // 碰
  canOperation.gangIt =false; // 杠某张打出的牌
  canOperation.huaAnGang = false; // 花暗杠
  canOperation.anGang = false; // 暗杠
  canOperation.mingGangAfterGrabbing = false;// 摸牌之后明杠
  canOperation.dianPao = false; // 点炮胡
  canOperation.ziMo = false; // 自摸胡
}

// 被激活的座次，比如正在出牌
const activeSeat = ref(-1);

let leftTilesCount = ref(0);

// 牌组对象
class TileGroup {
  type:string='';// 牌组类型
  tiles:Array<string>=new Array<string>();// 牌组的牌
  constructor(type:string, tiles:Array<string>) {
    this.type = type;
    this.tiles  = tiles;
  }
}

// 牌组对象
class HuaTileGroup {
  type:string='';// 牌组类型
  tiles:Array<string>=new Array<string>();// 牌组的牌
}

// 玩家对象
class Player {
  userId: string = ''; // userId
  name: string = '';// 用户名
  seat:number = -1; // 座次
  isReady:boolean = false; // 是否已准备
  ownedTilesCount: number = 0; // 拥有的手牌数量
  ownedTiles:Array<string> = new Array<string>();// 自己拥有的手牌 (只在玩家是自己时可用)
  ownedGroups:Array<TileGroup> = new Array<TileGroup>();// 拥有的牌组
  ownedHuaGroups:Array<HuaTileGroup> = new Array<HuaTileGroup>();// 拥有的花牌牌组
  playedTiles:Array<string> = new Array<string>();// 打出的牌
  isHu: boolean = false;//是否胡牌了
}

// 自己
let self = reactive(new Player());
self.userId = query.userId as string;

// 上家
let previousPlayer = reactive(new Player());
// 下家
let nextPlayer = reactive(new Player());
// 对家
let oppositePlayer = reactive(new Player());

// 自己拥有的手牌
// let selfOwnedTiles = ref(new Array<string>());
// 旁边的牌组
// let selfGroups = ref(new Array());
// selfGroups.push({type: 'CHI', tiles: ["YI_WAN", "ER_WAN","SAN_WAN"]});
// selfGroups.push({type: 'PENG', tiles: ["YI_WAN"]});
// selfGroups.push({type: 'MING_GANG', tiles: ["NAN_FENG"]});
// selfGroups.push({type: 'AN_GANG', tiles: ["NAN_FENG"]});

// 拥有的花组
// let ownedHuaGroups = ref(new Array());
// ownedHuaGroups.push({type: 'HEI_HUA', tiles: ["MEI","MEI","MEI"]});
// ownedHuaGroups.push({type: 'HONG_HUA', tiles: ["CHUN"]});
// ownedHuaGroups.push({type: 'BAI_BAN', tiles: ["BAI_BAN"]});

// 自己打出的牌
// let selfPlayedTiles = ref(new Array());
// selfPlayedTiles.push("NAN_FENG");


// let preGroups = ref(new Array());
// preGroups.push({type: 'MING_GANG', tiles: ["NAN_FENG"]});
// preGroups.push({type: 'CHI', tiles: ["YI_WAN", "ER_WAN","SAN_WAN"]});
// preGroups.push({type: 'AN_GANG'});
// preGroups.push({type: 'PENG', tiles: ["YI_WAN"]});
// preGroups.push({type: 'PENG', tiles: ["YI_WAN"]});

// let preHuaGroups = ref(new Array());
// preHuaGroups.push({type: 'HEI_HUA', tiles: ["MEI"]});
// preHuaGroups.push({type: 'HONG_HUA', tiles: ["CHUN","CHUN"]});
// preHuaGroups.push({type: 'BAI_BAN', tiles: ["BAI_BAN", "BAI_BAN", "BAI_BAN", "BAI_BAN"]});

// let prePlayedTiles = ref(new Array());
// prePlayedTiles.push("YI_WAN")
// prePlayedTiles.push("NAN_FENG");
// prePlayedTiles.push("NAN_FENG");
// prePlayedTiles.push("NAN_FENG");
// prePlayedTiles.push("NAN_FENG");
// prePlayedTiles.push("NAN_FENG");
// prePlayedTiles.push("ER_WAN");
// prePlayedTiles.push("ER_WAN");
// prePlayedTiles.push("ER_WAN");
// prePlayedTiles.push("ER_WAN");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("KE_JI");
// prePlayedTiles.push("ER_WAN");

// let nextGroups = new Array();
// nextGroups.push({type: 'CHI', tiles: ["YI_WAN", "ER_WAN","SAN_WAN"]});
// nextGroups.push({type: 'MING_GANG', tiles: ["NAN_FENG"]});
// nextGroups.push({type: 'AN_GANG'});
// nextGroups.push({type: 'PENG', tiles: ["YI_WAN"]});
// nextGroups.push({type: 'PENG', tiles: ["YI_WAN"]});
// nextGroups.push({type: 'CHI', tiles: ["YI_WAN", "ER_WAN","SAN_WAN"]});

// let nextHuaGroups = new Array();
// nextHuaGroups.push({type: 'HEI_HUA', tiles: ["MEI"]});
// nextHuaGroups.push({type: 'HONG_HUA', tiles: ["CHUN","CHUN"]});
// nextHuaGroups.push({type: 'BAI_BAN', tiles: ["BAI_BAN", "BAI_BAN"]});

// let nextPlayedTiles = new Array();
// nextPlayedTiles.push("YI_WAN")
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("KE_JI");
// nextPlayedTiles.push("ER_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");
// nextPlayedTiles.push("YI_WAN");


// let oppositeGroups = new Array();
// oppositeGroups.push({type: 'CHI', tiles: ["YI_WAN", "ER_WAN","SAN_WAN"]});
// oppositeGroups.push({type: 'PENG', tiles: ["YI_WAN"]});
// oppositeGroups.push({type: 'MING_GANG', tiles: ["NAN_FENG"]});
// oppositeGroups.push({type: 'AN_GANG', tiles: ["NAN_FENG"]});

// let oppositeHuaGroups = new Array();
// oppositeHuaGroups.push({type: 'HEI_HUA', tiles: ["MEI"]});
// oppositeHuaGroups.push({type: 'HONG_HUA', tiles: ["CHUN","CHUN"]});
// oppositeHuaGroups.push({type: 'BAI_BAN', tiles: ["BAI_BAN", "BAI_BAN", "BAI_BAN", "BAI_BAN"]});

// let oppositePlayedTiles = new Array<string>();
// oppositePlayedTiles.push("YI_WAN")
// oppositePlayedTiles.push("KE_JI");
// oppositePlayedTiles.push("KE_JI");
// oppositePlayedTiles.push("KE_JI");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");
// oppositePlayedTiles.push("ER_WAN");
// oppositePlayedTiles.push("SAN_WAN");


// 动态样式表
const styles = reactive({
  seatsStyle: {
    position: 'fixed',
    'z-index': 4000,
    left:'',
    top: ''
  },
  operationBtnsWrapStyle: {
    right: '',
    bottom: ''
  },
  selfAvatarStyle: {
    left: '',
    bottom: ''
  },
  selfPlayerOwnedGroupsStyle: {
    right: '',
    bottom: '15px'
  },
  selfPlayedTilesComponentStyle: {
    width: '',
    height: ''
  },
  ownedHuaGroupsBtnStyle: {
    position: 'fixed',
    'z-index': "4500",
    right: '',
    bottom: ''
  },
  readyBtnStyle: {
    position: 'fixed',
    'z-index': "11000",
    left: '',
    bottom: ''
  },
  huStateStyle: {
    position: 'fixed',
    'z-index': "20000",
    left: '',
    bottom: ''
  },
  prevoiusReadyStateStyle: {
    position: 'fixed',
    'z-index': "4700",
    left: '',
    bottom: ''
  },
  prevoiusHuStateStyle: {
    position: 'fixed',
    'z-index': "20000",
    left: '',
    bottom: ''
  },
  previousAvatarStyle: {
    left: '',
    bottom: ''
  },
  previousOwnedTilesStyle : {
    left: '',
    top: ''
  },
  previousPlayerOwnedGroupsStyle: {
    left: '',
    bottom: '50px'
  },
  previousHuaGroupsBtnStyle: {
    position: 'fixed',
    'z-index': "4100",
    left: '',
    bottom: ''
  },
  previousPlayedTilesStyle: {
    left: '',
    top: ''
  },
  previousPlayedTilesComponentStyle: {
    width: '',
    height: ''
  },
  nextReadyStateStyle: {
    position: 'fixed',
    'z-index': "4600",
    right: '',
    bottom: ''
  },
  nextHuStateStyle: {
    position: 'fixed',
    'z-index': "20000",
    right: '',
    bottom: ''
  },
  nextAvatarStyle: {
    right: '',
    bottom: ''
  },
  nextOwnedTilesStyle: {
    right: '',
    bottom: '120px'
  },
  nextPlayerOwnedGroupsStyle: {
    right: '10px',
    top: ''
  },
  nextHuaGroupsBtnStyle: {
    position: 'fixed',
    'z-index': "4200",
    right: '',
    bottom: ''
  },
  nextPlayedTilesStyle: {
    right: '',
    bottom: ''
  },
  nextPlayedTilesComponentStyle: {
    width: '',
    height: ''
  },
  oppositeReadyStateStyle: {
    position: 'fixed',
    'z-index': "4600",
    left: '',
    top: ''
  },
  oppositeHuStateStyle: {
    position: 'fixed',
    'z-index': "20000",
    left: '',
    top: ''
  },
  oppositeAvatarStyle: {
    left: '',
    top: ''
  },
  oppositeOwnedTilesStyle: {
    right: '',
    top: ''
  },
  oppositePlayerOwnedGroupsStyle: {
    left: '',
    top: ''
  },
  oppositeHuaGroupsBtnStyle: {
    position: 'fixed',
    'z-index': "4300",
    left: '',
    top: ''
  },
  oppositePlayedTilesStyle: {
    right: '',
    top: ''
  },
  oppositePlayedTilesComponentStyle: {
    width: '',
    height: ''
  }
}) 

function loadStyles() {
  // 获取桌子宽度
  let desktopOffsetWidth = (desktop as any).value.offsetWidth;
  // 获取桌子距离左边距离
  let desktopOffsetLeft = (desktop as any).value.offsetLeft;
    // 获取桌子距离顶部的距离
  let desktopOffsetTop = (desktop as any).value.offsetTop;
  // 获取桌子宽度
  let desktopOffsetHeight = (desktop as any).value.offsetHeight;

  // 座次
  styles.seatsStyle.left = desktopOffsetLeft + desktopOffsetWidth * 0.47 + "px"
  styles.seatsStyle.top = desktopOffsetTop + desktopOffsetHeight * 0.4 + "px"

  // 自己的手牌旁边吃碰杠等牌组位置
  styles.operationBtnsWrapStyle.right = desktopOffsetLeft + 200 + "px";
  styles.operationBtnsWrapStyle.bottom = "200px";
  styles.selfAvatarStyle.left = desktopOffsetLeft + 50 + "px";
  styles.selfAvatarStyle.bottom = "50px";
  styles.selfPlayerOwnedGroupsStyle.right = desktopOffsetLeft - 50 +  'px';
  styles.selfPlayedTilesComponentStyle.width = desktopOffsetWidth * 0.5 -210  + 'px';
  styles.selfPlayedTilesComponentStyle.height = desktopOffsetHeight * 0.5 - 100  + 'px';
  styles.ownedHuaGroupsBtnStyle.right = desktopOffsetLeft + 200 +  'px';
  styles.ownedHuaGroupsBtnStyle.bottom = '100px';
  styles.readyBtnStyle.left = desktopOffsetWidth* 0.5 +  'px';
  styles.readyBtnStyle.bottom = desktopOffsetHeight * 0.5 - 300 + "px";
  styles.huStateStyle.left = desktopOffsetWidth* 0.6 +  'px';
  styles.huStateStyle.bottom = desktopOffsetHeight * 0.5 - 300 + "px";

  // 上家
  styles.prevoiusReadyStateStyle.left = desktopOffsetLeft + 100 + "px";
  styles.prevoiusReadyStateStyle.bottom = desktopOffsetHeight * 0.4  + "px";
  styles.prevoiusHuStateStyle.left = desktopOffsetLeft + 250  + "px";
  styles.prevoiusHuStateStyle.bottom = desktopOffsetHeight * 0.45  + "px";
  styles.previousAvatarStyle.left = desktopOffsetLeft + 200 + "px";
  styles.previousAvatarStyle.bottom = desktopOffsetHeight * 0.5 + 50 + "px";
  styles.previousOwnedTilesStyle.left = desktopOffsetLeft + desktopOffsetWidth * 0.13 + 'px';
  styles.previousOwnedTilesStyle.top = desktopOffsetTop + desktopOffsetHeight * 0.2 + 'px';
  styles.previousPlayerOwnedGroupsStyle.left = desktopOffsetLeft - 60 + "px";
  styles.previousHuaGroupsBtnStyle.left = desktopOffsetLeft + 200  +  'px';
  styles.previousHuaGroupsBtnStyle.bottom = desktopOffsetHeight * 0.4 + "px";
  styles.previousPlayedTilesStyle.left = desktopOffsetLeft + 300  +  'px';
  styles.previousPlayedTilesStyle.top = desktopOffsetTop + 150 + "px";
  styles.previousPlayedTilesComponentStyle.width = desktopOffsetHeight * 0.5 -210  + 'px';
  styles.previousPlayedTilesComponentStyle.height = desktopOffsetWidth * 0.5 - 100  + 'px';

  // 下家
  styles.nextReadyStateStyle.right = desktopOffsetWidth * 0.12 + 'px'; 
  styles.nextReadyStateStyle.bottom = desktopOffsetHeight * 0.5 - 100 + 'px'; 
  styles.nextHuStateStyle.right = desktopOffsetWidth * 0.25 + 'px'; 
  styles.nextHuStateStyle.bottom = desktopOffsetHeight * 0.45 + 'px'; 
  styles.nextAvatarStyle.right = desktopOffsetLeft +  desktopOffsetWidth * 0.15 + 'px'; 
  styles.nextAvatarStyle.bottom = desktopOffsetHeight * 0.5 + 50 + 'px'; 
  styles.nextOwnedTilesStyle.right = desktopOffsetLeft +  desktopOffsetWidth * 0.05 + 'px'; 
  styles.nextPlayerOwnedGroupsStyle.top = desktopOffsetTop + desktopOffsetHeight * 0.1 + 'px';
  styles.nextPlayerOwnedGroupsStyle.right = desktopOffsetTop + desktopOffsetWidth * 0.15 + 'px';
  styles.nextHuaGroupsBtnStyle.right = desktopOffsetLeft + 200  +  'px';
  styles.nextHuaGroupsBtnStyle.bottom = desktopOffsetHeight * 0.4 + "px";
  styles.nextPlayedTilesStyle.right = desktopOffsetLeft + 250  +  'px';
  styles.nextPlayedTilesStyle.bottom = desktopOffsetTop + 300 + "px";
  styles.nextPlayedTilesComponentStyle.width = desktopOffsetHeight * 0.5 -210  + 'px';
  styles.nextPlayedTilesComponentStyle.height = desktopOffsetWidth * 0.5 - 100  + 'px';

  // 对家
  styles.oppositeReadyStateStyle.left = desktopOffsetWidth * 0.5 + 'px'; 
  styles.oppositeReadyStateStyle.top = desktopOffsetTop + 'px';   
  styles.oppositeHuStateStyle.left = desktopOffsetWidth * 0.6 + 'px'; 
  styles.oppositeHuStateStyle.top = desktopOffsetTop + 100 + 'px'; 
  styles.oppositeAvatarStyle.left = desktopOffsetLeft + desktopOffsetWidth * 0.5 + 'px'; 
  styles.oppositeAvatarStyle.top = desktopOffsetTop +  100 + 'px'; 
  styles.oppositeOwnedTilesStyle.right = desktopOffsetLeft +  desktopOffsetWidth * 0.2 + 'px'; 
  styles.oppositeOwnedTilesStyle.top = desktopOffsetTop +  desktopOffsetHeight * 0.05 + 'px';
  styles.oppositePlayerOwnedGroupsStyle.left = desktopOffsetLeft + desktopOffsetWidth * 0.12 + 'px';
  styles.oppositePlayerOwnedGroupsStyle.top = desktopOffsetTop + desktopOffsetHeight * 0.02 + 'px';
  styles.oppositeHuaGroupsBtnStyle.left = desktopOffsetWidth * 0.5  +  'px';
  styles.oppositeHuaGroupsBtnStyle.top = desktopOffsetTop  + 50 + "px";
  styles.oppositePlayedTilesStyle.right = desktopOffsetWidth * 0.5 -100  + 'px';
   styles.oppositePlayedTilesStyle.top = desktopOffsetTop   + 'px';
  styles.oppositePlayedTilesComponentStyle.width = desktopOffsetWidth * 0.5 - 100  + 'px';
  styles.oppositePlayedTilesComponentStyle.height = desktopOffsetHeight * 0.5 - 100  + 'px';
}

// 建立连接
function connect() {
    wsserver.connect(roomId, self.userId);
    wsserver.onOpen(() => {
      console.log("加入了");
    })
    wsserver.onMessage(onMessage);
    wsserver.onClose(() => {
      ElMessage.info("关闭了");
    })
    wsserver.onError(() => {
      ElMessage.info("错误了");
    })
}

// 根据userId获取玩家对象
function getPlayer(userId:string) {
    if (self.userId == userId) {
      return self;
    } else if (previousPlayer && previousPlayer.userId == userId) {
      return previousPlayer;
    } else if (nextPlayer && nextPlayer.userId == userId) {
      return nextPlayer;
    } else {
      return oppositePlayer;
    }
}

// 设置玩家状态
function setPlayerReadyState(userId:string, isReady:boolean) {
    let player = getPlayer(userId);
    player.isReady = isReady;
}


function setWelcomeMsgData(data:string) {
    let {selfInfo, previousInfo,nextInfo,oppositeInfo} = JSON.parse(data);
    self.name = selfInfo.name;
    self.seat = selfInfo.seat;
    self.isReady = selfInfo.isReady;
    if (previousInfo) {
      previousPlayer.name = previousInfo.name;
      previousPlayer.userId = previousInfo.userId;
      previousPlayer.seat = previousInfo.seat;
      previousPlayer.isReady = previousInfo.isReady;
    }
    if (nextInfo) {
      nextPlayer.name = nextInfo.name;
      nextPlayer.userId = nextInfo.userId;
      nextPlayer.seat = nextInfo.seat;
      nextPlayer.isReady = nextInfo.isReady;
    }
    if (oppositeInfo) {
      oppositePlayer.name = oppositeInfo.name;
      oppositePlayer.userId = oppositeInfo.userId;
      oppositePlayer.seat = oppositeInfo.seat;
      oppositePlayer.isReady = oppositeInfo.isReady;
    }
}

// 设置玩家加入信息
function setPlayerJoinInfo(data:string) {
  let dataObj = JSON.parse(data);
  let seat = dataObj.seat;
  // 如果自己是东家
  if (self.seat == 1) {
    if(seat == 2) {
      nextPlayer.name = dataObj.name;
      nextPlayer.userId = dataObj.userId;
      nextPlayer.seat = dataObj.seat;
    } else if (seat == 3) {
      oppositePlayer.name = dataObj.name;
      oppositePlayer.userId = dataObj.userId;
      oppositePlayer.seat = dataObj.seat;
    } else {
      previousPlayer.name = dataObj.name;
      previousPlayer.userId = dataObj.userId;
      previousPlayer.seat = dataObj.seat;
    }
  } else if (self.seat == 2) {
    if(seat == 3) {
      nextPlayer.name = dataObj.name;
      nextPlayer.userId = dataObj.userId;
      nextPlayer.seat = dataObj.seat;
    } else if (seat == 4) {
      oppositePlayer.name = dataObj.name;
      oppositePlayer.userId = dataObj.userId;
      oppositePlayer.seat = dataObj.seat;
    } else {
      previousPlayer.name = dataObj.name;
      previousPlayer.userId = dataObj.userId;
      previousPlayer.seat = dataObj.seat;
    }
  } else if (self.seat == 3) {
    if(seat == 4) {
      nextPlayer.name = dataObj.name;
      nextPlayer.userId = dataObj.userId;
      nextPlayer.seat = dataObj.seat;
    } else if (seat == 1) {
      oppositePlayer.name = dataObj.name;
      oppositePlayer.userId = dataObj.userId;
      oppositePlayer.seat = dataObj.seat;
    } else {
      previousPlayer.name = dataObj.name;
      previousPlayer.userId = dataObj.userId;
      previousPlayer.seat = dataObj.seat;
    }
  } else {
    if(seat == 1) {
      nextPlayer.name = dataObj.name;
      nextPlayer.userId = dataObj.userId;
      nextPlayer.seat = dataObj.seat;
    } else if (seat == 2) {
      oppositePlayer.name = dataObj.name;
      oppositePlayer.userId = dataObj.userId;
      oppositePlayer.seat = dataObj.seat;
    } else {
      previousPlayer.name = dataObj.name;
      previousPlayer.userId = dataObj.userId;
      previousPlayer.seat = dataObj.seat;
    }
  }
}


// 获取花牌列表
function getHuaFromOwnedTiles(tiles:Array<string>) {
  let result = new Array<string>();
  tiles.forEach(tile => {
    // 是花牌，但是非百搭，才能补
    if (isHua(tile) && !isVersatile(tile)) {
      result.push(tile);
    }
  });
  return result;
}

// 从手牌中移除这些牌
function removeFromOwnedTiles(tiles:Array<string>) {
  tiles.forEach(tile => {
    let index = self.ownedTiles.indexOf(tile);
    if (index >= 0) {
      self.ownedTiles.splice(index, 1);
    }
  })
}

  // 显示这一家正在操作
function setActiveSeat(userId:string) {
  let player = getPlayer(userId);
  activeSeat.value = player.seat;
}

// 重新开始之前的初始化
function setRestartPlayers() {
  lastTile.value = '';
  isHu.value = false;
  versatileTiles.value = new Array();
  chiItGroups.value = new Array();
  huaAnGangGroups.value = new Array();
  anGangTiles.value = new Array();
  mingGangTilesAfterGrabbing.value = new Array();
  
  self.ownedGroups = new Array();
  self.ownedHuaGroups = new Array();
  self.ownedTiles = new Array();
  self.ownedTilesCount = 0;
  self.playedTiles = new Array();
  self.isHu = false;

  previousPlayer.ownedGroups = new Array();
  previousPlayer.ownedHuaGroups = new Array();
  previousPlayer.ownedTiles = new Array();
  previousPlayer.ownedTilesCount = 0;
  previousPlayer.playedTiles = new Array();
  previousPlayer.isHu = false;

  nextPlayer.ownedGroups = new Array();
  nextPlayer.ownedHuaGroups = new Array();
  nextPlayer.ownedTiles = new Array();
  nextPlayer.ownedTilesCount = 0;
  nextPlayer.playedTiles = new Array();
  nextPlayer.isHu = false;

  oppositePlayer.ownedGroups = new Array();
  oppositePlayer.ownedHuaGroups = new Array();
  oppositePlayer.ownedTiles = new Array();
  oppositePlayer.ownedTilesCount = 0;
  oppositePlayer.playedTiles = new Array();
  nextPlayer.isHu = false;
}

// 设置起手手牌
function setStartTiles(data:any) {
  inProgress.value = true;
  let dataObj = JSON.parse(data);
  let {ownedTiles, firstSupplementUserId, bankerUserId, otherCountList} = dataObj;
  self.ownedTiles = ownedTiles;
  versatileTiles.value = dataObj.versatileTiles;

  anGangTiles.value = dataObj.anGangTiles;
  if (anGangTiles.value && anGangTiles.value.length > 0) {
    canOperation.anGang = true;
  }
  canOperation.ziMo = dataObj.canZiMo;
  
  for (var i=0; i<otherCountList.length; i++) {
    let {userId, count} = otherCountList[i];
    let player = getPlayer(userId);
    player.ownedTilesCount = count;
  }
  // 如果有补花，则先补花
  if (firstSupplementUserId) {
      // 显示这一家正在补花
      setActiveSeat(firstSupplementUserId)
      // 如果首先轮到自己，则提示起手补花按钮
    if (firstSupplementUserId == self.userId) {
      canOperation.buHuaWhenStart = true;
    }
  } 
  // 如果没人可以补花，则庄家先出牌
  else {
    setActiveSeat(bankerUserId);
    if (bankerUserId == self.userId) {
      // canOperation.playCard = true;
    }
  }
}

// 重连后设置自己的数据
function setSelfDataWhenSelfReconnect(data:any) {
  self.name = data.name;
  self.seat= data.seat;
  self.ownedTiles = data.ownedTiles;
  self.ownedGroups = data.ownedTilesGroup;
  self.ownedHuaGroups = data.ownedHuaTilesGroup;
  self.playedTiles = data.playedTiles;
}

// 自己重连时设置其他家数据
function setOthersDataWhenSelfReconnect(data:any) {
    let {previousInfo, nextInfo, oppositeInfo} = data;
    // 上家
    previousPlayer.name = previousInfo.name;
    previousPlayer.userId = previousInfo.userId;
    previousPlayer.ownedTilesCount = previousInfo.ownedTilesCount;
    previousPlayer.ownedGroups = previousInfo.ownedTilesGroup;
    previousPlayer.ownedHuaGroups = previousInfo.ownedHuaTilesGroup;
    previousPlayer.playedTiles = previousInfo.playedTiles;
    previousPlayer.seat = previousInfo.seat;

    // 下家
    nextPlayer.name = nextInfo.name;
    nextPlayer.userId = nextInfo.userId;
    nextPlayer.ownedTilesCount = nextInfo.ownedTilesCount;
    nextPlayer.ownedGroups = nextInfo.ownedTilesGroup;
    nextPlayer.ownedHuaGroups = nextInfo.ownedHuaTilesGroup;
    nextPlayer.playedTiles = nextInfo.playedTiles;
    nextPlayer.seat = nextInfo.seat;

    // 对家
    oppositePlayer.name = oppositeInfo.name;
    oppositePlayer.userId = oppositeInfo.userId;
    oppositePlayer.ownedTilesCount = oppositeInfo.ownedTilesCount;
    oppositePlayer.ownedGroups = oppositeInfo.ownedTilesGroup;
    oppositePlayer.ownedHuaGroups = oppositeInfo.ownedHuaTilesGroup;
    oppositePlayer.playedTiles = oppositeInfo.playedTiles;
    oppositePlayer.seat = oppositeInfo.seat;
}

// 设置可以拥有的操作
function setReconnectCanOperation(dataObj:any) {
    let canOperationData = dataObj.canOperation;
    // canOperation.playCard = canOperationData.playCard;
    canOperation.buHuaWhenStart =  canOperationData.buHuaWhenStart;// 起手补花
    canOperation.buHua = canOperationData.buHua; // 普通补花
    canOperation.chi =  canOperationData.chi; // 吃
    canOperation.peng = canOperationData.peng; // 碰
    canOperation.gangIt = canOperationData.gangIt; // 杠某张打出的牌
    canOperation.huaAnGang = canOperationData.huaAnGang; // 花暗杠
    canOperation.anGang = canOperationData.anGang; // 暗杠
    canOperation.mingGangAfterGrabbing = canOperationData.mingGangAfterGrabbing; // 摸牌之后明杠
    canOperation.dianPao =  canOperationData.dianPao; // 点炮胡
    canOperation.ziMo =  canOperationData.ziMo; // 自摸胡
}

// 别人打牌之后自己这边吃牌、碰牌等提醒
function handleOperationAfterPlayedTile(dataObj:any) {
  let { canChiIt, canPengIt,canMingGangIt, canDianPaoIt} = dataObj;
  canOperation.chi = canChiIt;
  chiItGroups.value = dataObj.chiItGroups
  canOperation.peng = canPengIt;
  canOperation.gangIt = canMingGangIt;
  canOperation.dianPao = canDianPaoIt;
}

// 消息处理
function onMessage(event:any) {
  console.log("收到服务端消息>>>>", event.data);
  let msgBody = JSON.parse(event.data);
  
  let code = msgBody.code;
  let data = msgBody.data;
  // 加入房间提醒，接收房间内的所有用户信息
  if (code == msgtype.WELCOME) {
    setWelcomeMsgData(data);
    initCanOperation();
  } 
  // 其他玩家加入房间提醒
  else if (code == msgtype.OTHER_JOIN) {
    setPlayerJoinInfo(data);
  }
  // 重连
  else if (code == msgtype.RECONNECT) {
    let dataObj = JSON.parse(data);
    setSelfDataWhenSelfReconnect(dataObj);
    setOthersDataWhenSelfReconnect(dataObj);
    // 激活的座次
    setActiveSeat(dataObj.playingUserId);
    // 百搭牌
    versatileTiles.value = dataObj.versatileTiles;
    leftTilesCount.value = dataObj.leftTilesCount;

    
    lastTile.value = dataObj.lastTile;
    chiItGroups.value = dataObj.chiItGroups;
    huaAnGangGroups.value = dataObj.huaAnGangGroups;
    anGangTiles.value = dataObj.anGangTiles;
    mingGangTilesAfterGrabbing.value = dataObj.mingGangTilesAfterGrabbing;
    setReconnectCanOperation(dataObj);
    inProgress.value = true;
  }
  // 玩家状态 
  else if (code == msgtype.USER_STATUS) {
    let {userId, status} = JSON.parse(data);
    // 是否已准备
    setPlayerReadyState(userId, status == operation.READY)
  } 
  // 起手发牌
  else if (code == msgtype.START_TILES) {
    initCanOperation();
    setRestartPlayers();
    setStartTiles(data);
  }
  // 起手补花提醒
  else if (code == msgtype.SUPPLEMENT_WHEN_START_REMINDER) {
    let {userId} = JSON.parse(data);
    // 显示这一家正在补花
    setActiveSeat(userId);
    if (userId == self.userId) {
      canOperation.buHuaWhenStart = true;
    } else {
      canOperation.buHuaWhenStart = false;
    }
  }
  // 自己补花结束后的通知
  else if (code == msgtype.SELF_SUPPLEMENT) {
    let dataObj = JSON.parse(data);
    let {ownedTiles,ownedHuaGroups,isSupplementWhenStart} = dataObj;
    // 补花结束后拥有的手牌
    self.ownedTiles = ownedTiles;
    self.ownedHuaGroups = ownedHuaGroups;
    // 判断是否起始补花
    if (!isSupplementWhenStart) {
      let tile = dataObj.tiles[0];
      // 如果是花牌并且不是百搭，则自动继续补花
      if (isHua(tile) && !isVersatile(tile)) {
        wsserver.send({
          operation: operation.SUPPLEMENT,
          data: tile
        })
      }
    }
  }
  // 其他人补花
  else if (code == msgtype.OTHER_SUPPLEMENT) {
    let {userId, huaGroups} = JSON.parse(data);
    let player = getPlayer(userId);
    player.ownedHuaGroups = huaGroups;
  }
  // 剩余可抓的牌数量提醒
  else if (code == msgtype.LEFT_TILES_COUNT) {
    let {count} = JSON.parse(data);
    leftTilesCount.value = count;
  } 
  // 轮到某位玩家出牌提醒
  else if (code == msgtype.PLAY_REMINDER) {
    let dataObj = JSON.parse(data);
    let {userId} = dataObj;
    setActiveSeat(userId);
    // 是否轮到自己出牌
    if (userId == self.userId) {
      anGangTiles.value = dataObj.anGangTiles;
      if (anGangTiles.value && anGangTiles.value.length > 0) {
        canOperation.anGang = true;
      }
      canOperation.ziMo = dataObj.canZiMo;
    }
  }
  // 某为玩家出了某张牌的提醒
  else if (code == msgtype.PLAYED_CARD) {
    let dataObj = JSON.parse(data);
    let {userId, nextUserId,canNextGrabbing,tile} = dataObj;
    if (self.userId == userId) {
      // 隐藏按钮
      // initCanOperation();
      // 手牌中移除这张牌
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      // 放到打出的牌中
      self.playedTiles.push(tile);
    } else {
      // 刚刚出牌的人
      let thePlayer = getPlayer(userId);
      thePlayer.ownedTilesCount -= 1;
      thePlayer.playedTiles.push(tile);
    }
    lastTile.value = tile;
    // 下一位出牌者
    let nextPlayer = getPlayer(nextUserId);
    // 如果下架可以抓牌，则方向标移到下家身上
    if(canNextGrabbing) {
      activeSeat.value = nextPlayer.seat;
      if (self.userId == nextUserId) {
        wsserver.send({
          operation: operation.GRABBING
        })
      }
    } else {
      // 出牌后显示自己可以做的操作
      handleOperationAfterPlayedTile(dataObj);
    }
  }
  // 玩家吃完牌的提醒
  else if (code == msgtype.CHI) {
    let {userId,previousUserId, tiles, selectedTiles} = JSON.parse(data);
    let player = getPlayer(userId);
    activeSeat.value = player.seat;
    player.ownedGroups.push(new TileGroup(tilesgroup.CHI, tiles));
    if (userId == self.userId) {
      // 去除选择的这两张牌
      for (var i=0;i<selectedTiles.length;i++) {
        self.ownedTiles.splice(self.ownedTiles.indexOf(selectedTiles[i]), 1);
      }
    } else {
      player.ownedTilesCount -= 2;
    }
    // 移除上家打出的最后那张牌
    let previousPlayer = getPlayer(previousUserId);
    previousPlayer.playedTiles.splice(previousPlayer.playedTiles.length-1, 1);
  } 
  // 玩家碰完牌的提醒
  else if (code == msgtype.PENG) {
    let {userId, tile, playedUserId} = JSON.parse(data);
    // 去除那个出牌人的最后一个出的牌
    let playedPlayer = getPlayer(playedUserId);
    playedPlayer.playedTiles.splice(playedPlayer.playedTiles.length - 1, 1);

    let player = getPlayer(userId);
    activeSeat.value = player.seat;
    // 推进用户牌组
    player.ownedGroups.push(new TileGroup(tilesgroup.PENG, [tile, tile, tile]))
    // 如果是自己碰牌，则移除手中那两张牌
    if (self.userId == userId) {
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
    } else {// 如果是别人，则扣除那个用户手中的手牌数量
      player.ownedTilesCount -= 2;
    }
  }
  // 玩家杠完牌的提醒
  else if (code == msgtype.MING_GANG_IT) {
    let {userId, tile, playedUserId} = JSON.parse(data);
    // 去除那个出牌人的最后一个出的牌
    let playedPlayer = getPlayer(playedUserId);
    playedPlayer.playedTiles.splice(playedPlayer.playedTiles.length - 1, 1);
    canOperation.gangIt = false;
    let player = getPlayer(userId);
    activeSeat.value = player.seat;
    player.ownedGroups.push(new TileGroup(tilesgroup.MING_GANG, [tile, tile, tile, tile]))
    if (self.userId == userId) {
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      // 抓牌
      wsserver.send({
        operation: operation.GRABBING
      })
    } else {
      player.ownedTilesCount -= 3;
    }
  }
  // 抓完牌后明杠的提醒
  else if (code == msgtype.MING_GANG_AFTER_GRABBING) {
    let dataObj = JSON.parse(data);
    let {userId, tile} = dataObj;
    let player = getPlayer(userId);
    player.ownedGroups = dataObj.ownedGroups;
    canOperation.mingGangAfterGrabbing =  false;
    mingGangTilesAfterGrabbing.value = new Array();
    // 移除这张手牌
    if (self.userId == userId) {
      self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
      // 抓牌
      wsserver.send({
        operation: operation.GRABBING
      })
    } else {
      player.ownedTilesCount -= 1;
    }
  }
  // 暗杠完成后推送给个人的消息
  else if (code == msgtype.SELF_AN_GANG) {
    let {tile} = JSON.parse(data);
    self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
    self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
    self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
    self.ownedTiles.splice(self.ownedTiles.indexOf(tile), 1);
    self.ownedGroups.push(new TileGroup(tilesgroup.AN_GANG, [tile]))
    // 抓牌
    wsserver.send({
      operation: operation.GRABBING
    })
  }
  // 其他玩家暗杠提醒
  else if (code == msgtype.OTHER_AN_GANG) {
    let {userId} = JSON.parse(data);
    let player = getPlayer(userId);
    // 其他玩家手牌-4张
    player.ownedTilesCount -= 4;
    // 牌组加上暗杠
    player.ownedGroups.push(new TileGroup(tilesgroup.AN_GANG, []));
  }
  // 自己抓到牌提醒
  else if (code == msgtype.SELF_GRABBING) {
    let dataObj = JSON.parse(data);
    activeSeat.value = self.seat;
    let {ownedTiles, tile} = dataObj;
    self.ownedTiles = ownedTiles;
    mingGangTilesAfterGrabbing.value = dataObj.mingGangTiles;
    if (mingGangTilesAfterGrabbing.value && mingGangTilesAfterGrabbing.value.length > 0) {
      canOperation.mingGangAfterGrabbing = true;
    }
    anGangTiles.value = dataObj.anGangTiles;
    if (anGangTiles.value && anGangTiles.value.length > 0) {
      canOperation.anGang = true;
    }
    canOperation.ziMo = dataObj.canZiMo;
    // 如果是花牌并且不是百搭，则自动补花
    if (isHua(tile) && !isVersatile(tile)) {
      wsserver.send({
        operation: operation.SUPPLEMENT,
        data: tile
      })
    }
  }
  // 别人抓到牌的提醒
  else if (code == msgtype.OTHER_GRABBING) {
    let {userId} = JSON.parse(data);
    let player = getPlayer(userId);
    player.ownedTilesCount += 1;
    activeSeat.value = player.seat;
  }
  else if (code == msgtype.HU) {
    let {userId, othersOwnedTiles, othersGroups, playedUserId, isDianPao} = JSON.parse(data);
    let player = getPlayer(userId);
    player.isHu = true;
    if (isDianPao) {
      // 去除那个出牌人的最后一个出的牌
      let playedPlayer = getPlayer(playedUserId);
      playedPlayer.playedTiles.splice(playedPlayer.playedTiles.length - 1, 1);
    }
    // 渲染其他人的手牌
    for (var uid in othersOwnedTiles) {
      let player = getPlayer(uid);
      player.ownedTiles = othersOwnedTiles[uid]; 
      player.ownedTilesCount = othersOwnedTiles[uid].length;
      player.isReady = false;
    }
    // 渲染其他人的牌组，主要是为了翻出暗杠的牌
    for (var uid in othersGroups) {
      let player = getPlayer(uid);
      player.ownedGroups = othersGroups[uid]; 
    }
    isHu.value = true;
    inProgress.value = false;
    self.isReady = false;
  }
  // 没有剩余牌可以抓
  else if (code == msgtype.NO_REMAINING_TILES) {
    let {othersOwnedTiles, othersGroups} = JSON.parse(data);
    // 渲染其他人的手牌
    for (var uid in othersOwnedTiles) {
      let player = getPlayer(uid);
      player.ownedTiles = othersOwnedTiles[uid]; 
      player.ownedTilesCount = othersOwnedTiles[uid].length;
      player.isReady = false;
    }
    // 渲染其他人的牌组，主要是为了翻出暗杠的牌
    for (var uid in othersGroups) {
      let player = getPlayer(uid);
      player.ownedGroups = othersGroups[uid]; 
    }
    inProgress.value = false;
    self.isReady = false;
  }
  // 错误提示
  else if (code == msgtype.ERROR){
    ElMessage.info(data);
  } else {
    ElMessage.info("未知指令", msgBody);
  }
}

// 准备/取消准备
function handleReadyState() {
  // 如果当前是准备状态，则需要取消准备，反之亦然
  wsserver.send({
    operation: self.isReady ? operation.UN_READY : operation.READY
  });
}

// 起手补花
function handleBuHuaWhenStart() {
  // 获取花牌，并从手牌中移除
  let huaTiles = getHuaFromOwnedTiles(self.ownedTiles);
  removeFromOwnedTiles(huaTiles);
  // 发送起手补花消息
  wsserver.send({
    operation: operation.SUPPLEMENT_WHEN_START,
    data: huaTiles
  })
  // 隐藏补花按钮c
  initCanOperation();
}

// 出牌
function playTile(tile:string) {
  wsserver.send({
    operation: operation.PLAY_THE_CARD,
    data: tile
  })
}

// 吃牌
function handleChi(it:string, tiles:Array<string>) {
  let selectedGroup = new Array<string>();
  for (var i=0; i<tiles.length; i++) {
    if (tiles[i] != it) {
      selectedGroup.push(tiles[i])
    }
  }
  wsserver.send({
    operation: operation.CHI,
    data: {
      it: it,
      selectedGroup: selectedGroup.join(',')
    }
  })
  initCanOperation();
}

function giveUpOperation() {
  wsserver.send({
    operation: operation.GIVE_UP_OPERATION
  })
  initCanOperation();
}

// 碰牌操作
function handlePeng(tile:string) {
  wsserver.send({
    operation: operation.PENG,
    data: tile
  })
  initCanOperation();
}

function handleAnGang(tile:string) {
  wsserver.send({
    operation: operation.AN_GANG,
    data: tile
  })
  initCanOperation();
}

function handleDianPao(tile:string) {
  wsserver.send({
    operation: operation.DIAN_PAO,
    data: tile
  })
  initCanOperation();
}

function handleZiMo() {
  wsserver.send({
    operation: operation.ZI_MO
  })
  initCanOperation();
}

function handleMingGangTilesAfterGrabbing(tile:string) {
  wsserver.send({
    operation: operation.MING_GANG_AFTER_GRABBING,
    data: tile
  })
  initCanOperation();
}

function handleGangIt(tile:string) {
  wsserver.send({
    operation: operation.MING_GANG_IT,
    data: tile
  })
  initCanOperation();
}
onMounted(() => {
  connect();
  loadStyles();
})

onUpdated(() => {
  loadStyles();
})
</script>

<template>
  <div class="room">
    <div class="desktop" ref="desktop">
    </div>
  </div>
  <!-- 准备状态 -->
  <div v-if="!inProgress" class="btn-ready-wrap" @click="handleReadyState" :style="(styles.readyBtnStyle as any)">
    <el-button class="btn-ready" color="#409EFF" type="success" circle >
      <el-icon  :size="80" color="white"><Close v-if="self.isReady" /><Check v-else/></el-icon>
    </el-button>
    <div class="ready-text">{{self.isReady?'取消准备':'准备'}}</div>
  </div>
  <HuState :style="styles.huStateStyle" v-if="self.isHu"></HuState>
  <Operations 
    :style="styles.operationBtnsWrapStyle"
    @handleBuHuaWhenStart="handleBuHuaWhenStart"
    @handleChi="handleChi"
    @handleGiveUp="giveUpOperation"
    @handlePeng="handlePeng"
    @handleGangIt="handleGangIt"
    @handleAnGang="handleAnGang"
    @handleDianPao="handleDianPao"
    @handleZiMo="handleZiMo"
    @handleMingGangTilesAfterGrabbing="handleMingGangTilesAfterGrabbing"
    :it="lastTile"
    :buHuaWhenStart = "canOperation.buHuaWhenStart"
    :buHua = "canOperation.buHua"
    :chi = "canOperation.chi"
    :peng = "canOperation.peng"
    :gangIt = "canOperation.gangIt"
    :anGang = "canOperation.anGang"
    :dianPao = "canOperation.dianPao"
    :ziMo="canOperation.ziMo"
    :chiItGroups = "chiItGroups"
    :anGangTiles = "anGangTiles"
    :mingGangTilesAfterGrabbing = "mingGangTilesAfterGrabbing"
  />
  <Seats :selfSeat="self.seat" :style="styles.seatsStyle" :activeSeat="activeSeat"></Seats>
  <el-card shadow="always" class="left-tiles-count"> 剩余:  {{leftTilesCount}} 张</el-card>
  <!-- 百搭牌 -->
  <div v-if="versatileTiles.length > 0" class="versatile-tiles-wrap">
    <div class="versatile-tiles-title">百搭牌</div>
    <VersatileTiles :tiles="versatileTiles"></VersatileTiles>
  </div>
  <!-- 自己 -->
  <div class="avatar" :style="styles.selfAvatarStyle">
    <el-avatar :icon="UserFilled" > </el-avatar>
    <div class="name">{{self.name}}</div>
  </div>
  <OwnedHuaGroups :btnPositionStyle="styles.ownedHuaGroupsBtnStyle" btnText="个人花牌" placement="left" :groups="self.ownedHuaGroups"></OwnedHuaGroups>
  <div class="self-player-owned-tiles">
    <OwnedTiles :versatileTiles="versatileTiles" :isHu="isHu" @playTile="playTile" :tiles="self.ownedTiles"></OwnedTiles>
  </div>
  <div class="self-player-owned-groups" :style="styles.selfPlayerOwnedGroupsStyle">
    <OwnedTilesGroups :groups="self.ownedGroups"></OwnedTilesGroups>
  </div>
  <div class="self-player-played-tiles">
    <PlayedTiles :tiles="self.playedTiles" :style="styles.selfPlayedTilesComponentStyle"></PlayedTiles>
  </div>
  <!-- 上家 -->
  <ReadyState :style="styles.prevoiusReadyStateStyle" v-if="previousPlayer.isReady && !inProgress"/>
  <HuState :style="styles.prevoiusHuStateStyle" v-if="previousPlayer.isHu"></HuState>
  <div class="avatar" :style="styles.previousAvatarStyle">
    <el-avatar :icon="UserFilled" > </el-avatar>
    <div class="name">{{previousPlayer.name}}</div>
  </div>
  <OwnedHuaGroups :btnPositionStyle="styles.previousHuaGroupsBtnStyle" btnText="上家花牌" placement="right" :groups="previousPlayer.ownedHuaGroups"></OwnedHuaGroups>
  <div class="pre-player-owned-tiles" :style="styles.previousOwnedTilesStyle">
    <PreviousOwnedTiles :tiles="previousPlayer.ownedTiles" :tilesSize="previousPlayer.ownedTilesCount"></PreviousOwnedTiles>
  </div>
  <div class="pre-player-owned-groups" :style="styles.previousPlayerOwnedGroupsStyle">
    <PreviousOwnedTilesGroups :groups="previousPlayer.ownedGroups"></PreviousOwnedTilesGroups>
  </div>
  <div class="pre-player-played-tiles" :style="styles.previousPlayedTilesStyle">
    <PreviousPlayedTiles :tiles="previousPlayer.playedTiles" :style="styles.previousPlayedTilesComponentStyle"></PreviousPlayedTiles>
  </div>
  <!-- 下家 -->
  <ReadyState :style="styles.nextReadyStateStyle" v-if="nextPlayer.isReady && !inProgress"/>
  <HuState :style="styles.nextHuStateStyle" v-if="nextPlayer.isHu"></HuState>
  <div class="avatar" :style="styles.nextAvatarStyle">
    <el-avatar :icon="UserFilled" > </el-avatar>
    <div class="name">{{nextPlayer.name}}</div>
  </div>
  <OwnedHuaGroups :btnPositionStyle="styles.nextHuaGroupsBtnStyle" btnText="下家花牌" placement="left" :groups="nextPlayer.ownedHuaGroups"></OwnedHuaGroups>
  <div class="next-player-owned-tiles" :style="styles.nextOwnedTilesStyle">
    <NextOwnedTiles :tiles="nextPlayer.ownedTiles" :tilesSize="nextPlayer.ownedTilesCount"></NextOwnedTiles>    
  </div>
  <div class="next-player-owned-groups" :style="styles.nextPlayerOwnedGroupsStyle">
    <NextOwnedTilesGroups :groups="nextPlayer.ownedGroups"></NextOwnedTilesGroups>
  </div>
  <div class="next-player-played-tiles" :style="styles.nextPlayedTilesStyle">
    <NextPlayedTiles :tiles="nextPlayer.playedTiles" :style="styles.nextPlayedTilesComponentStyle"></NextPlayedTiles>
  </div>
  <!-- 对家 -->
  <ReadyState :style="styles.oppositeReadyStateStyle" v-if="oppositePlayer.isReady && !inProgress"/>
  <HuState :style="styles.oppositeHuStateStyle" v-if="oppositePlayer.isHu"></HuState>
  <div class="avatar" :style="styles.oppositeAvatarStyle">
    <el-avatar :icon="UserFilled" > </el-avatar>
    <div class="name">{{oppositePlayer.name}}</div>
  </div>
  <OwnedHuaGroups :btnPositionStyle="styles.oppositeHuaGroupsBtnStyle" btnText="对家花牌" placement="bottom" :groups="oppositePlayer.ownedHuaGroups"></OwnedHuaGroups>
  <div class="opposite-player-owned-tiles" :style="styles.oppositeOwnedTilesStyle">
    <OppositeOwnedTiles :tiles="oppositePlayer.ownedTiles" :tilesSize="oppositePlayer.ownedTilesCount"></OppositeOwnedTiles>  
  </div>
  <div class="opposite-player-owned-groups" :style="styles.oppositePlayerOwnedGroupsStyle">
    <OppositeOwnedTilesGroups :groups="oppositePlayer.ownedGroups"></OppositeOwnedTilesGroups>  
  </div>
  <div class="opposite-player-played-tiles" :style="styles.oppositePlayedTilesStyle">
    <OppositePlayedTiles :tiles="oppositePlayer.playedTiles" :style="styles.oppositePlayedTilesComponentStyle"></OppositePlayedTiles>  
  </div>
</template>
<style scoped lang="scss">
.room {
  position: relative;
  top :0; 
  left: 0; 
  right: 0; 
  bottom:0;
  z-index: -90;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: flex-end;
  transform-style: preserve-3d;
  perspective: 300px;
  perspective-origin: 50% 0px;
  overflow: hidden;
  .desktop {
    position: relative;
    // bottom: 200px;
    width: 90%;
    height: 100%;
    border-radius: 50px;
    border: 10px solid rgb(78, 78, 82);
    transform: rotateX(10deg);
    background-image: url("/images/background/desktop.jpg");
    background-color: black;
    // background:linear-gradient(45deg,#78C9DB 50%,#0acf00 50%);
    background-repeat: no-repeat;
    background-size: 100% 100%;
  }
} 

.operation-btns-wrap {
  position: fixed;
  z-index: 5000;
}
.avatar{
  position: fixed;
  z-index: 4600;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  .name{
    color: white;
  }
}
.btn-ready-wrap{
  text-align: center;
  .ready-text{
    font-size: 30px;
    color: white;
  }
  .btn-ready{
    width: 100px;
    height: 100px;
  }
}

.left-tiles-count {
  position: fixed;
  left: 20px;
  top: 50px;
  background-color: #337ecc;
  color: #ffffff;
}
.versatile-tiles-wrap {
  position: fixed;
  right: 5px;
  top: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: var(--el-box-shadow-dark);
  border-radius: 10px;
  background-color: #409EFF;
  .versatile-tiles-title{
    font-size: 20px;
    font-weight: bold;
  }
}
.self-player-owned-tiles {
  position: fixed;
  bottom: 0;
  left: 25%;
  right: 0;
  width: 100%;
  z-index: 10000;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

.pre-player-owned-tiles {
    position: fixed;
    z-index: 100;
    display: flex;
    flex-direction: column;
    justify-content: center ;
}


.next-player-owned-tiles {
    position: fixed;
    z-index: 100;
    display: flex;
    flex-direction: column;
    justify-content: center ;
}

.opposite-player-owned-tiles {
    position: fixed;
    z-index: 100;
    display: flex;
    flex-direction: row;
    justify-content: center ;
}
.self-player-owned-groups{
  position: fixed;
  z-index: 900;
}
.self-player-played-tiles {
  position: fixed;
  left:0;
  right: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 3500;
}
.pre-player-owned-groups{
  position: fixed;
}
.pre-player-played-tiles{
  position: fixed;
}
.next-player-owned-groups {
  position: fixed;
}

.next-player-played-tiles{
  position: fixed;
}
.opposite-player-owned-groups{
  position: fixed;
}
.opposite-player-played-tiles {
  position: fixed;
  // left:0;
  // right: 0;
  // top: 0;
  // width: 100%;
  // display: flex;
  // justify-content: center;
  // align-items: center;
  z-index: 3400;
}
</style>